﻿#pragma once

#include "Polynomial.h"
#include "linear_math.h"
#include <functional>

namespace CAGD
{

using Func11 = std::function<double(double)>; // 一元函数 R -> R
using FuncX1 = std::function<double(Vector)>; // 多元函数 Rn -> R
using Func1X = std::function<Vector(double)>; // 一元向量函数 R -> Rn
using FuncXX = std::function<Vector(Vector)>; // 多元向量函数 Rn -> Rm

//////////////////////////////////////////////////////////////////////////////////////////
///
///

/**
 * @file nonlinmath.h
 * @author xingyifan
 * @date 2022-12-01 22:14
 *
 * @description: 求解多元隐式方程的根
 */

class NewtonSolver
{
  public:
    double operator()(Func11 f, double x); // 一元函数的根
    void operator()(FuncXX f, Vector &x);  // 多元函数求根
};

//////////////////////////////////////////////////////////////////////////////////////////
///
///

/**
 * @file nonlinmath.h
 * @author xingyifan
 * @date 2022-12-01 22:17
 *
 * @description: Jacobi 算子
 */

class Jacobian
{
  public:
    Matrix operator()(FuncXX f, const Vector &x) const; // 多元向量函数的 Jacobi 矩阵
    Matrix operator()(FuncX1 f, const Vector &x) const; // 多元函数的 Jacobi 矩阵
    Vector operator()(Func1X f, double x) const;        // 一元向量函数的导向量
    double operator()(Func11 f, double x) const;        // 一元函数的导数
};

//////////////////////////////////////////////////////////////////////////////////////////
///
///

/**
 * @file nonlinmath.h
 * @author xingyifan
 * @date 2022-12-01 23:57
 *
 * @description: 积分器
 */

class Integrator
{
  protected:
    Vector m_weights; // 积分权

  public:
    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-12-02 00:02
     *
     * @description: 初始化积分权
     */

    Integrator(int N);

    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-07-28 00:11
     *
     * @description: 一元函数积分
     */

    virtual double operator()(Func11 f, double a, double b) const = 0;

    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-12-01 23:43
     *
     * @description: 获取操作
     */

    int order() const;
    Vector weights() const;
};

//////////////////////////////////////////////////////////////////////////////////////////
///
///

/**
 * @file nonlinmath.h
 * @author xingyifan
 * @date 2022-12-01 22:53
 *
 * @description: 牛顿积分器
 */

class NewtonCotes : public Integrator
{
  public:
    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-07-28 00:18
     *
     * @description: 在构造函数中初始化权重
     */

    NewtonCotes(int N);

    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-07-28 00:11
     *
     * @description: 一元函数积分
     */

    virtual double operator()(Func11 f, double a, double b) const;
};

//////////////////////////////////////////////////////////////////////////////////////////
///
///

/**
 * @file nonlinmath.h
 * @author xingyifan
 * @date 2022-12-01 23:53
 *
 * @description: 高斯积分器
 */

class GaussIntegrator : public Integrator
{
  public:
    Vector m_nodes; // 积分节点

  public:
    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-12-01 23:54
     *
     * @description: 构造初始化权和节点
     */

    GaussIntegrator(int N);

    /**
     * @file nonlinmath.h
     * @author xingyifan
     * @date 2022-12-01 23:55
     *
     * @description: 一元函数积分
     */

    virtual double operator()(Func11 f, double a, double b) const;

    /**
     * @file: nonlinmath.h
     * @author: xingyifan
     * @date: 2023-04-20 16:07
     *
     * @description: 获取积分节点
     */

    Vector nodes() const;
};

} // namespace CAGD
